package ro.gateway.aida.struts.action;

import java.util.Set;
import java.util.SortedSet;
import java.util.Vector;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.tiles.actions.TilesAction;

import ro.gateway.aida.db.PersistenceManager;
import ro.gateway.aida.db.PersistenceToken;
import ro.gateway.aida.struts.form.EditGroupForm;
import ro.gateway.aida.usr.Arbiter;
import ro.gateway.aida.usr.GroupRole;
import ro.gateway.aida.usr.Perms;
import ro.gateway.aida.usr.User;
import ro.gateway.aida.usr.UserDB;
import ro.gateway.aida.usr.UserGroup;
import ro.gateway.aida.usr.UserGroupDB;
import ro.gateway.aida.usr.UserUtils;
import ro.gateway.aida.utils.BugTracker;
import ro.gateway.aida.utils.SortedList;
import ro.gateway.aida.utils.Utils;


/**
 * EditGroupAction.java created by EasyStruts - XsltGen.
 * http://easystruts.sf.net
 * created on 09-12-2003
 *
 * XDoclet definition:
 * @struts:action path="/editgroup" name="editgroupForm" attribute="editGroupForm" input="/usr/editgroup.jsp" validate="true"
 */
public class EditGroupAction extends TilesAction {
    // --------------------------------------------------------- Instance Variables
    // --------------------------------------------------------- Methods
    private void msg(HttpServletRequest request, String message) {
        request.setAttribute("verbose", message);
    }

    /**
     * Method execute
     * @param ActionMapping mapping
     * @param ActionForm form
     * @param HttpServletRequest request
     * @param HttpServletResponse response
     * @return ActionForward
     * @throws Exception
     */
    public ActionForward execute(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response) {
        try {
            EditGroupForm egf = (EditGroupForm) form;
            ServletContext sc = getServlet().getServletContext();

            String act = request.getParameter("act");
			PersistenceToken token = PersistenceManager.
							tokenLookup(sc );
            //accessors
            UserGroupDB ugdb = UserGroupDB.getManager(token);
            UserDB udb = UserDB.getManager(token);

            User user = UserUtils.getLogged(request, response);

            if (user == null)
                return mapping.findForward("plslogin");

            Arbiter ar = Arbiter.getManager(token);

            if (!ar.canDo(request, Perms.ADMIN_TOOLS)) {
                HttpSession session = request.getSession();
                session.invalidate();

                return mapping.findForward("norights");
            }

            if ("toviewgroups".equals(act)) {
				Utils.setBreadCrumbs(request,"bc.groups.view");
                return mapping.findForward("viewgroups");
            }

            if ("delete".equals(act)) {
                int id = Integer.parseInt(request.getParameter("id"));
                
                //TODO: internal error page!
                if(id!=1){
                	ugdb.wipeGroup(id);
                	ugdb.deleteGroup(id);
                	Utils.setBreadCrumbs(request,"bc.groups.view");
                	return mapping.findForward("viewgroups");
                }
            } else if ("toviewgroups".equals(act)) {
				Utils.setBreadCrumbs(request,"bc.groups.view");
                return mapping.findForward("viewgroups");
            }
            //get project info
            //if we have an id in egf, then we get sg list and userlist
            if (egf.getId() != 0) {
                int id = egf.getId();

                if (request.getParameter("del_sg") != null) {
                    ugdb.unlinkSuperGroup(id, egf.getSgAdd());
                    msg(request, "Relation deleted.");
                }

                if (request.getParameter("add_sg") != null) {
                    //we want to add a supergroup
                    if (egf.getSgAdd() == id)
                        msg(request,
                            "You cannot add the same supergroup as the edited group!");
                    else {
                        boolean sgadded = ugdb.addSuperGroup(id, egf.getSgAdd());

                        if (sgadded)
                            msg(request, "Supergroup relation added");
                        else
                            msg(request, "Relation already exists!");
                    }
                }

                UserGroup ug = ugdb.getById(id);

                if (request.getParameter("add_update") == null) {
                    egf.setName(ug.getName());
                    egf.setDescription(ug.getDescription());
                    egf.setRole(ug.getRole().getId());
                    egf.setId(id);
                }

                if (request.getParameter("add_user") != null) {
                    //we want to add an user to the existent group
                    ugdb.addUser(id, egf.getUserAdd());
                    msg(request, "User added to group.");
                }

                if ((request.getParameter("del_user") != null) && (ugdb.getUserCount(id)>1 || !(ug.getRole().getId() == GroupRole.ADMINISTRATOR_ROLE ))) {
                    //we want to delete an user from the existent group,but NOT when the group has admin role and has only one user
                	ugdb.unlinkUser(id, egf.getUserAdd());
                    msg(request, "User removed from group.");
                }

                //deploy supergroups for this group
                SortedSet supergroups = ug.getSuperGroups();

                if (ug.getRole().getId() == GroupRole.ADMINISTRATOR_ROLE)
                    request.setAttribute("noSgroups", new String());

                request.setAttribute("supergroups", supergroups);

                //deploy users for this group  
                Vector group_users = ugdb.getUsers(id);
                request.setAttribute("assigned_users", group_users);
            }

            // id!=0
            if (request.getParameter("add_update") != null) {
                UserGroup ug = new UserGroup();
                ug.setName(egf.getName());
                ug.setDescription(egf.getDescription());
                ug.setRole(GroupRole.createRole(egf.getRole()));

                //do we have an add or an update?
                if (egf.getId() == 0) {
                    //add new group
                    egf.setId(ugdb.addGroup(ug));
                    msg(request,
                        "Group Added! You may now add users and supergroups from the form below");
                } else if(egf.getId()!=1){
                    //update name, description & roles
                    ug.setId(egf.getId());
                    ugdb.updateGroup(ug);

                    if (ug.getRole().getId() == GroupRole.ADMINISTRATOR_ROLE)
                        request.setAttribute("noSgroups", new String());
                    else
                        request.removeAttribute("noSgroups");

                    msg(request, "Name, descrition and role updated!");
                }
            }

            //creating supergroups/roles/users dropdowns
            Set groups = ugdb.createGroupList();
            request.setAttribute("groups", groups);

            //get user list
            SortedList users = udb.getAll();
            request.setAttribute("users", users);

            //deploy roles
            Vector roles = GroupRole.createAllRoles();
            request.setAttribute("roles", roles);
			Utils.setBreadCrumbs(request,"bc.groups.edit");
            return mapping.getInputForward();
        } catch (Exception e) {
            BugTracker.publishBug(e, request);

            return mapping.findForward("fail");
        }
    }
}
